package com.feishu.listener;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.feishu.base.type.ClassificationTypeEnum;
import com.feishu.base.type.OutJsonTypeEnum;
import com.feishu.rpc.core.SendHttpServer;
import com.feishu.service.FeiShuCommonService;
import com.hustcad.plm.pdm.ec.module.dto.ECObjData;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowChgFormView;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowObject;
import com.hustcad.plm.pdm.flowbusiness.model.entity.WorkFlowObjectPackage;
import com.hustcad.plm.pdm.user.model.dto.PdmUserDTO;
import com.hustcad.plm.pdm.user.service.TyplmUserService;
import com.hustcad.plm.pdm.workflow.annotion.CustomListener;
import com.hustcad.plm.pdm.workflow.annotion.CustomListenerField;
import com.hustcad.plm.pdm.workflow.model.entity.UserTaskDTO;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainerView;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerService;

import com.ty.basic.entity.org.UserDO;
import com.ty.basic.exception.message.SystemErrorCodeEnum;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.engine.impl.el.FixedValue;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.util.TaskHelper;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.task.service.delegate.DelegateTask;


import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@CustomListener(
        category = "飞书通用接口监听",
        description = "飞书通用接口"
)
public class FeishuListener implements  TaskListener {

    @CustomListenerField(
            description = "飞书三方审批创建接口编码",
            defaultValue = "",
            required = true
    )
    private FixedValue code;

    @CustomListenerField(
            description = "飞书三方审批创建接口对象",
            defaultValue = "",
            required = true
    )
    private FixedValue fsObject;


    @CustomListenerField(
            description = "飞书三方审批同步编码",
            defaultValue = "",
            required = true
    )
    private FixedValue synCode;

    @CustomListenerField(
            description = "飞书三方审批同步对象",
            defaultValue = "",
            required = true
    )
    private FixedValue synObject;

    @CustomListenerField(
            description = "飞书三方审批bot编码",
            defaultValue = "",
            required = true
    )
    private FixedValue botCode;

    @CustomListenerField(
            description = "飞书三方审批bot对象",
            defaultValue = "",
            required = true
    )
    private FixedValue botObject;

    @CustomListenerField(
            description = "审核对象（对象不同，页面不同）",
            defaultValue = "",
            required = true
    )
    private FixedValue audit;
    @Override
    public void notify(DelegateTask delegateTask) {
        TyplmWorkFlowContainerService typlmWorkFlowContainerService = SpringUtil.getBean(TyplmWorkFlowContainerService.class);
        TyplmUserService typlmUserService = SpringUtil.getBean(TyplmUserService.class);

        BigInteger workFlowContainerId = new BigInteger(delegateTask.getVariable("workFlowContainerId").toString());
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(workFlowContainerId);

        if (workFlowContainerView instanceof WorkFlowObjectPackage) {
            WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
            if (workFlowObjectPackage.getFlowObjectList() != null && workFlowObjectPackage.getFlowObjectList()
                    .size() != 0) {

                FlowObject flowObject = null;
                for(int i=0;i<workFlowObjectPackage.getFlowObjectList().size();i++){
                    flowObject=workFlowObjectPackage.getFlowObjectList().get(i);
                    String oType = flowObject.getRefObjectOtype();
                    if("ty.inteplm.part.CTyPart".equals(oType)){
                        break;
                    }
                    else if("ty.inteplm.form.CTyFormData".equals(oType)){
                        break;
                    }
                }
                UserDO taskUserDO = typlmUserService.queryUserByKey(workFlowObjectPackage.getCreatorOid());
                UserDO approvalUserDO = typlmUserService.queryUserByKey(new BigInteger(delegateTask.getAssignee()));

                SendHttpServer sendHttpServer = SpringUtil.getBean(SendHttpServer.class);

                Map<String,Object> threadMap=new HashMap<>();
                threadMap.put("botCode",this.botCode.getExpressionText());
                threadMap.put("botObject",this.botObject.getExpressionText());
                threadMap.put("synCode",this.synCode.getExpressionText());
                threadMap.put("synObject",this.synObject.getExpressionText());
                threadMap.put("audit",this.audit.getExpressionText());

                threadMap.put("workFlowContainerId",workFlowContainerId.toString());
                threadMap.put("auditStatus","PENDING");
                threadMap.put("instance_id",delegateTask.getProcessInstanceId());
                threadMap.put("start_time",System.currentTimeMillis());
                threadMap.put("end_time",System.currentTimeMillis());
                threadMap.put("deploymentId",workFlowContainerView.getDeploymentId());
                String activityId=delegateTask.getTaskDefinitionKey();
                threadMap.put("activityId",activityId);
                threadMap.put("taskId",delegateTask.getId());
                threadMap.put("code",workFlowContainerView.getCode());
                threadMap.put("name",workFlowContainerView.getName());
                threadMap.put("creatorAccount",workFlowContainerView.getCreatorAccount());
                threadMap.put("workFlowName",workFlowContainerView.getWorkFlowName());
                threadMap.put("emergencyDegreeName",workFlowContainerView.getEmergencyDegreeName());
                threadMap.put("refObjectOid",flowObject.getRefObjectOid().toString());
                threadMap.put("plmUserId",approvalUserDO.getOid().toString());
                threadMap.put("processInstanceId",delegateTask.getProcessInstanceId());

                for(int i=0;i<workFlowObjectPackage.getUserTaskList().size();i++){
                    if(activityId.equals(workFlowObjectPackage.getUserTaskList().get(i).getId())){
                        threadMap.put("UserTask",workFlowObjectPackage.getUserTaskList().get(i).getUserList());
                        break;
                    }
                }

                org.flowable.engine.TaskService descTaskService= SpringUtil.getBean(org.flowable.engine.TaskService.class);
                String executionsJson= (String) descTaskService.getVariable(delegateTask.getId(),"executionstrategy");

                JSONObject executionstrategy=null;
                JSONArray ExtensionElement=JSONArray.parseArray(executionsJson);
                if(ExtensionElement.size()>0){
                    String elementText=ExtensionElement.getJSONObject(0).getString("elementText");
                    executionstrategy=JSONObject.parseObject(elementText);
                }
                if(executionstrategy!=null){
                    threadMap.put("executionstrategy",executionstrategy);
                }

                List<JSONObject> feishuUserList=new ArrayList<>();
                List<String> phones=new ArrayList<>();
                List<PdmUserDTO>  userTaskDTOS= (List<PdmUserDTO>) threadMap.get("UserTask");
                for(int i=0;i<userTaskDTOS.size();i++){
                    UserDO feishuUser = typlmUserService.queryUserByKey(new BigInteger(userTaskDTOS.get(i).getOid()));
                    feishuUserList.add(JSONObject.parseObject(JSONObject.toJSONString(feishuUser)));
                    phones.add(feishuUser.getTelephone());
                }
                phones.add(taskUserDO.getTelephone());
                phones.add(approvalUserDO.getTelephone());



                JSONArray feishuList=sendHttpServer.getUserIdDataToServer(this.botCode.getExpressionText(),
                                                                          this.botObject.getExpressionText(),
                                                                          OutJsonTypeEnum.OUT_JSON_TYPE_FEISHU,
                                                                          ClassificationTypeEnum.DEFAULT.setValue("ordinaryMessage"), phones);
                if(feishuList==null){
                    throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException("流程发起人或审核人飞书查不到用户");
                }

                for(int y=0;y<feishuUserList.size();y++){
                    for(int i=0;i<feishuList.size();i++){
                        if(feishuUserList.get(y).getString("telephone").equals(feishuList.getJSONObject(i).getString("mobile"))){
                            feishuUserList.get(y).put("feishuId",feishuList.getJSONObject(i).getString("user_id"));
                            break;
                        }
                    }
                }

                threadMap.put("feishuUserList",feishuUserList);

                for(int i=0;i<feishuList.size();i++){
                    if(taskUserDO.getTelephone().equals(feishuList.getJSONObject(i).getString("mobile"))){
                        threadMap.put("submitId",feishuList.getJSONObject(i).getString("user_id"));
                        break;
                    }
                }
                for(int i=0;i<feishuList.size();i++){
                    if(approvalUserDO.getTelephone().equals(feishuList.getJSONObject(i).getString("mobile"))){
                        threadMap.put("approvalId",feishuList.getJSONObject(i).getString("user_id"));
                        break;
                    }
                }

                FeiShuCommonService feiShuCommonService = SpringUtil.getBean(FeiShuCommonService.class);
                JSONObject resultHttp=new JSONObject();
                resultHttp.put("code",0);

                if("无策略".equals(executionstrategy.getString("name"))) {
                    Map<String,Object> select=new HashMap<>();
                    select.put("processInstanceId",delegateTask.getProcessInstanceId());
                    List<Map<String,Object>> feishuCodeList=feiShuCommonService.getFeiShuApprovalCode(select);
                    if(feishuCodeList.size()==0){
                        resultHttp=sendHttpServer.sendUserDataToServer(this.code.getExpressionText(),
                                                                                  this.fsObject.getExpressionText(),
                                                                                  OutJsonTypeEnum.OUT_JSON_TYPE_FEISHU,
                                                                                  ClassificationTypeEnum.DEFAULT.setValue("ordinaryMessage"),
                                                                                  flowObject,threadMap);
                    }
                }
                else if("一票决策".equals(executionstrategy.getString("name"))) {
                    Map<String,Object> select=new HashMap<>();
                    select.put("processInstanceId",delegateTask.getProcessInstanceId());
                    List<Map<String,Object>> feishuCodeList=feiShuCommonService.getFeiShuApprovalCode(select);
                    if(feishuCodeList.size()==0){
                        resultHttp=sendHttpServer.sendUserDataToServer(this.code.getExpressionText(),
                                                                       this.fsObject.getExpressionText(),
                                                                       OutJsonTypeEnum.OUT_JSON_TYPE_FEISHU,
                                                                       ClassificationTypeEnum.DEFAULT.setValue("ordinaryMessage"),
                                                                       flowObject,threadMap);
                    }
                    else{
                        String plmUserJsonStr= (String) feishuCodeList.get(0).get("task_id");
                        JSONObject plmUserJson=JSONObject.parseObject(plmUserJsonStr);
                        String plmUserId= (String) threadMap.get("plmUserId");
                        plmUserJson.put(plmUserId,delegateTask.getId());
                        feishuCodeList.get(0).put("task_id",plmUserJson.toJSONString());
                        feiShuCommonService.updateFeiShuApprovalCodeTask(feishuCodeList.get(0));
                    }
                }

                if(resultHttp.containsKey("code")==false){
                    throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(resultHttp);
                }
                if(resultHttp.getLongValue("code")!=0){
                    throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(resultHttp.getString("msg"));
                }
            }
        }
        else if(workFlowContainerView instanceof FlowChgFormView){
            FlowChgFormView flowChgFormView = (FlowChgFormView) workFlowContainerView;
            if(flowChgFormView.getChgFormVO().getEcAffectVOS()!=null){
                List<FlowObject> flowObjectList=new ArrayList<>();
                for (int i = 0; i < flowChgFormView.getChgFormVO().getEcAffectVOS().size(); i++) {
                    ECObjData ecObjData = flowChgFormView.getChgFormVO().getEcAffectVOS().get(i);
                    BigInteger partOid = ecObjData.getRefObjectOid();
                    String oType = ecObjData.getRefObjectOtype();
                    FlowObject flowObject=new FlowObject();
                    flowObject.setRefObjectOid(partOid);
                    flowObject.setRefObjectOtype(oType);
                    flowObjectList.add(flowObject);
                }

                FlowObject flowObject = null;

                for(int i=0;i<flowObjectList.size();i++){
                    flowObject=flowObjectList.get(i);
                    String oType = flowObject.getRefObjectOtype();
                    if("ty.inteplm.part.CTyPart".equals(oType)){
                        break;
                    }
                    else if("ty.inteplm.form.CTyFormData".equals(oType)){
                        break;
                    }
                }

                UserDO taskUserDO = typlmUserService.queryUserByKey(flowChgFormView.getCreatorOid());
                UserDO approvalUserDO = typlmUserService.queryUserByKey(new BigInteger(delegateTask.getAssignee()));

                SendHttpServer sendHttpServer = SpringUtil.getBean(SendHttpServer.class);

                Map<String,Object> threadMap=new HashMap<>();
                threadMap.put("botCode",this.botCode.getExpressionText());
                threadMap.put("botObject",this.botObject.getExpressionText());
                threadMap.put("synCode",this.synCode.getExpressionText());
                threadMap.put("synObject",this.synObject.getExpressionText());
                threadMap.put("audit",this.audit.getExpressionText());

                threadMap.put("auditStatus","PENDING");
                threadMap.put("instance_id",delegateTask.getId());
                threadMap.put("start_time",System.currentTimeMillis());
                threadMap.put("end_time",System.currentTimeMillis());
                threadMap.put("deploymentId",workFlowContainerView.getDeploymentId());
                threadMap.put("activityId",delegateTask.getTaskDefinitionKey());
                threadMap.put("taskId",delegateTask.getId());
                threadMap.put("code",workFlowContainerView.getCode());
                threadMap.put("name",workFlowContainerView.getName());
                threadMap.put("creatorAccount",workFlowContainerView.getCreatorAccount());
                threadMap.put("workFlowName",workFlowContainerView.getWorkFlowName());
                threadMap.put("emergencyDegreeName",workFlowContainerView.getEmergencyDegreeName());
                threadMap.put("refObjectOid",flowObject.getRefObjectOid().toString());
                threadMap.put("plmUserId",approvalUserDO.getOid().toString());

                List<String> phones=new ArrayList<>();

                phones.add(taskUserDO.getTelephone());
                phones.add(approvalUserDO.getTelephone());
                JSONArray feishuList=sendHttpServer.getUserIdDataToServer(this.botCode.getExpressionText(),
                                                                          this.botObject.getExpressionText(),
                                                                          OutJsonTypeEnum.OUT_JSON_TYPE_FEISHU,
                                                                          ClassificationTypeEnum.DEFAULT.setValue("ordinaryMessage"), phones);
                for(int i=0;i<feishuList.size();i++){
                    if(taskUserDO.getTelephone().equals(feishuList.getJSONObject(i).getString("mobile"))){
                        threadMap.put("submitId",feishuList.getJSONObject(i).getString("user_id"));
                        break;
                    }
                }
                for(int i=0;i<feishuList.size();i++){
                    if(approvalUserDO.getTelephone().equals(feishuList.getJSONObject(i).getString("mobile"))){
                        threadMap.put("approvalId",feishuList.getJSONObject(i).getString("user_id"));
                        break;
                    }
                }


                JSONObject resultHttp=sendHttpServer.sendUserDataToServer(this.code.getExpressionText(),
                                                                          this.fsObject.getExpressionText(),
                                                                          OutJsonTypeEnum.OUT_JSON_TYPE_FEISHU,
                                                                          ClassificationTypeEnum.DEFAULT.setValue("ordinaryMessage"),
                                                                          flowObject,threadMap);
                if(resultHttp.containsKey("code")==false){
                    throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(resultHttp);
                }
                if(resultHttp.getLongValue("code")!=0){
                    throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(resultHttp.getString("msg"));
                }

            }
            else if(flowChgFormView.getChgFormVO().getEcObjDataVOS()!=null){
                List<FlowObject> flowObjectList=new ArrayList<>();
                for (int i = 0; i < flowChgFormView.getChgFormVO().getEcObjDataVOS().size(); i++) {
                    ECObjData ecObjData = flowChgFormView.getChgFormVO().getEcObjDataVOS().get(i);
                    BigInteger partOid = ecObjData.getOid();
                    String oType = ecObjData.getOtype();
                    FlowObject flowObject=new FlowObject();
                    flowObject.setRefObjectOid(partOid);
                    flowObject.setRefObjectOtype(oType);
                    flowObjectList.add(flowObject);
                }

                FlowObject flowObject = flowObjectList.get(0);
                UserDO taskUserDO = typlmUserService.queryUserByKey(flowChgFormView.getCreatorOid());
                UserDO approvalUserDO = typlmUserService.queryUserByKey(new BigInteger(delegateTask.getAssignee()));

                SendHttpServer sendHttpServer = SpringUtil.getBean(SendHttpServer.class);

                Map<String,Object> threadMap=new HashMap<>();
                threadMap.put("botCode",this.botCode.getExpressionText());
                threadMap.put("botObject",this.botObject.getExpressionText());
                threadMap.put("synCode",this.synCode.getExpressionText());
                threadMap.put("synObject",this.synObject.getExpressionText());
                threadMap.put("audit",this.audit.getExpressionText());

                threadMap.put("auditStatus","PENDING");
                threadMap.put("instance_id",delegateTask.getId());
                threadMap.put("start_time",System.currentTimeMillis());
                threadMap.put("end_time",System.currentTimeMillis()+1000*60*60*24*7);
                threadMap.put("deploymentId",workFlowContainerView.getDeploymentId());
                threadMap.put("activityId",delegateTask.getTaskDefinitionKey());
                threadMap.put("taskId",delegateTask.getId());
                threadMap.put("code",workFlowContainerView.getCode());
                threadMap.put("name",workFlowContainerView.getName());
                threadMap.put("creatorAccount",workFlowContainerView.getCreatorAccount());
                threadMap.put("workFlowName",workFlowContainerView.getWorkFlowName());
                threadMap.put("emergencyDegreeName",workFlowContainerView.getEmergencyDegreeName());
                threadMap.put("refObjectOid",workFlowContainerView.getBaseObjectOid().toString());
                threadMap.put("plmUserId",approvalUserDO.getOid().toString());

                List<String> phones=new ArrayList<>();

                phones.add(taskUserDO.getTelephone());
                phones.add(approvalUserDO.getTelephone());
                JSONArray feishuList=sendHttpServer.getUserIdDataToServer(this.botCode.getExpressionText(),
                                                                          this.botObject.getExpressionText(),
                                                                          OutJsonTypeEnum.OUT_JSON_TYPE_FEISHU,
                                                                          ClassificationTypeEnum.DEFAULT.setValue("ordinaryMessage"), phones);
                for(int i=0;i<feishuList.size();i++){
                    if(taskUserDO.getTelephone().equals(feishuList.getJSONObject(i).getString("mobile"))){
                        threadMap.put("submitId",feishuList.getJSONObject(i).getString("user_id"));
                        break;
                    }
                }
                for(int i=0;i<feishuList.size();i++){
                    if(approvalUserDO.getTelephone().equals(feishuList.getJSONObject(i).getString("mobile"))){
                        threadMap.put("approvalId",feishuList.getJSONObject(i).getString("user_id"));
                        break;
                    }
                }


                JSONObject resultHttp=sendHttpServer.sendUserDataToServer(this.code.getExpressionText(),
                                                                          this.fsObject.getExpressionText(),
                                                                          OutJsonTypeEnum.OUT_JSON_TYPE_FEISHU,
                                                                          ClassificationTypeEnum.DEFAULT.setValue("ordinaryMessage"),
                                                                          flowObject,threadMap);
                if(resultHttp.containsKey("code")==false){
                    throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(resultHttp);
                }
                if(resultHttp.getLongValue("code")!=0){
                    throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(resultHttp.getString("msg"));
                }

            }
        }
    }

}
